//! 测试配置管理模块
//! 用于读取和管理测试配置

use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;

pub mod mysql_config_test;

/// 数据库配置
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct DatabaseConfig {
    pub enabled: bool,
    pub mysql: MySqlConfig,
    pub postgres: PostgresConfig,
    pub sqlite: SqliteConfig,
}

/// MySQL配置
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct MySqlConfig {
    pub host: String,
    pub port: u16,
    pub database: String,
    pub username: String,
    pub password: String,
    pub connection_string: String,
}

/// PostgreSQL配置
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PostgresConfig {
    pub host: String,
    pub port: u16,
    pub database: String,
    pub username: String,
    pub password: String,
    pub connection_string: String,
}

/// SQLite配置
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SqliteConfig {
    pub path: String,
    pub connection_string: String,
}

/// 测试配置
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TestConfig {
    pub parallel: bool,
    pub timeout_seconds: u64,
    pub retry_count: usize,
    pub data_generation: DataGenerationConfig,
    pub performance: PerformanceConfig,
}

/// 数据生成测试配置
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct DataGenerationConfig {
    pub batch_size: usize,
    pub sample_count: usize,
}

/// 性能测试配置
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PerformanceConfig {
    pub enabled: bool,
    pub iterations: usize,
    pub warmup_iterations: usize,
}

/// 特性配置
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct FeatureConfig {
    pub database_enabled: bool,
    pub tracing_enabled: bool,
}

/// 完整的测试配置
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TestConfiguration {
    pub database: DatabaseConfig,
    pub test: TestConfig,
    pub features: FeatureConfig,
}

impl TestConfiguration {
    /// 从文件加载配置
    pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self, Box<dyn std::error::Error>> {
        let contents = fs::read_to_string(path)?;
        let config: TestConfiguration = toml::from_str(&contents)?;
        Ok(config)
    }

    /// 从默认路径加载配置
    pub fn load_default() -> Result<Self, Box<dyn std::error::Error>> {
        Self::load_from_file("tests/config/test_config.toml")
    }

    /// 创建MySQL连接配置
    pub fn create_mysql_connection_config(&self) -> dataforge::filling::ConnectionConfig {
        dataforge::filling::ConnectionConfig::mysql(
            &self.database.mysql.host,
            &self.database.mysql.database,
            &self.database.mysql.username,
            &self.database.mysql.password,
        )
        .with_port(self.database.mysql.port)
    }

    /// 创建PostgreSQL连接配置
    pub fn create_postgres_connection_config(&self) -> dataforge::filling::ConnectionConfig {
        dataforge::filling::ConnectionConfig::postgres(
            &self.database.postgres.host,
            &self.database.postgres.database,
            &self.database.postgres.username,
            &self.database.postgres.password,
        )
        .with_port(self.database.postgres.port)
    }

    /// 创建SQLite连接配置
    pub fn create_sqlite_connection_config(&self) -> dataforge::filling::ConnectionConfig {
        dataforge::filling::ConnectionConfig::sqlite(&self.database.sqlite.path)
    }

    /// 检查是否启用数据库测试
    pub fn is_database_test_enabled(&self) -> bool {
        self.database.enabled && self.features.database_enabled
    }

    /// 获取MySQL连接字符串
    pub fn mysql_connection_string(&self) -> &str {
        &self.database.mysql.connection_string
    }

    /// 获取PostgreSQL连接字符串
    pub fn postgres_connection_string(&self) -> &str {
        &self.database.postgres.connection_string
    }

    /// 获取SQLite连接字符串
    pub fn sqlite_connection_string(&self) -> &str {
        &self.database.sqlite.connection_string
    }

    /// 获取测试超时时间（秒）
    pub fn test_timeout_seconds(&self) -> u64 {
        self.test.timeout_seconds
    }

    /// 获取重试次数
    pub fn retry_count(&self) -> usize {
        self.test.retry_count
    }

    /// 检查是否启用性能测试
    pub fn is_performance_test_enabled(&self) -> bool {
        self.test.performance.enabled
    }

    /// 获取性能测试迭代次数
    pub fn performance_iterations(&self) -> usize {
        self.test.performance.iterations
    }

    /// 获取预热迭代次数
    pub fn warmup_iterations(&self) -> usize {
        self.test.performance.warmup_iterations
    }

    /// 获取批处理大小
    pub fn batch_size(&self) -> usize {
        self.test.data_generation.batch_size
    }

    /// 获取样本数量
    pub fn sample_count(&self) -> usize {
        self.test.data_generation.sample_count
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_config_loading() {
        let config = TestConfiguration::load_default().expect("Failed to load test config");
        
        // 验证基本配置加载
        assert_eq!(config.database.enabled, true);
        assert_eq!(config.database.mysql.host, "localhost");
        assert_eq!(config.database.mysql.port, 13308);
        assert_eq!(config.test.parallel, true);
        assert_eq!(config.features.database_enabled, true);
    }

    #[test]
    fn test_config_helpers() {
        let config = TestConfiguration::load_default().expect("Failed to load test config");
        
        // 验证辅助方法
        assert_eq!(config.is_database_test_enabled(), true); // 因为database.enabled = true
        assert_eq!(config.postgres_connection_string(), "postgresql://postgres:postgres123@localhost:5432/dataforge_test");
        assert_eq!(config.sqlite_connection_string(), "sqlite::memory:");
        assert_eq!(config.test_timeout_seconds(), 30);
        assert_eq!(config.is_performance_test_enabled(), true);
        assert_eq!(config.performance_iterations(), 1000);
        assert_eq!(config.batch_size(), 100);
        assert_eq!(config.sample_count(), 1000);
    }
}